/**
 * 权限控制指令方法
 * @author luguoxiang
 * @date 2021-09-07
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { has } from '@/soar';

/**
 * 权限控制指令
 * 验证权限：
 *    普通用法：v-has:permit="'权限'"
 *    简写：v-has="'权限'"
 *    匹配其中一个：v-has:permit="[ '权限1', '权限2', '权限n' ]"
 *    匹配所有：v-has:permit.all="[ '权限1', '权限2', '权限n' ]"
 *    字符串配置：v-has:permit="'权限1,权限2,权限n'"
 *    排除（取反）：v-has:permit.exclude="'权限1,权限2,权限n'" 不是以上权限的可显示
 *    严格模式：v-has:permit.strict="'权限1,权限2,权限n'" 忽略超级管理员
 *    禁用模式：v-has:permit.disabled="'权限1,权限2,权限n'" 无指定权限禁用点击事件
 *    隐藏模式：v-has:permit.hidden="'权限1,权限2,权限n'" 无指定权限隐藏元素
 *    多重修饰：v-has:permit.all.exclude.strict="'权限1,权限2,权限n'"
 * 验证角色：
 *    普通用法：v-has:role="'角色'"
 *    简写：v-has:r="'角色'"
 *    匹配其中一个：v-has:role="[ '角色1', '角色2', '角色n' ]"
 *    匹配所有：v-has:role.all="[ '角色1', '角色2', '角色n' ]"
 *    字符串配置：v-has:role="'角色1,角色2,角色n'"
 *    排除（取反）：v-has:role.exclude="'角色1,角色2,角色n'" 不是以上角色的可显示
 *    严格模式：v-has:role.strict="'角色1,角色2,角色n'" 忽略超级管理员
 *    禁用模式：v-has:role.disabled="'角色1,角色2,角色n'" 无指定角色禁用点击事件
 *    隐藏模式：v-has:role.hidden="'角色1,角色2,角色n'" 无指定角色隐藏元素
 *    多重修饰：v-has:role.all.exclude.strict="'角色1,角色2,角色n'"
 * 验证用户类型：
 *    普通用法：v-has:userType="'用户类型'"
 *    简写：v-has:ut="'用户类型'"
 *    匹配其中一个：v-has:userType="[ 用户类型1, 用户类型2, 用户类型n ]"
 *    字符串配置：v-has:userType="'用户类型1,用户类型2,用户类型n'"
 *    排除（取反）：v-has:userType.exclude="'用户类型1,用户类型2,用户类型n'" 不是以上用户类型的可显示
 *    严格模式：v-has:userType.strict="'用户类型1,用户类型2,用户类型n'" 忽略超级管理员
 *    禁用模式：v-has:userType.disabled="'用户类型1,用户类型2,用户类型n'" 非指定用户类型禁用点击事件
 *    隐藏模式：v-has:userType.hidden="'用户类型1,用户类型2,用户类型n'" 非指定用户类型隐藏元素
 *    多重修饰：v-has:userType.all.exclude.strict="'用户类型1,用户类型2,用户类型n'"
 * 验证超级管理员：v-has:admin
 */ // @ts-ignore
function handle(el: any, { arg, value, modifiers }) {
  const flag = has(arg, value, modifiers);
  // 禁用模式（无权限不删除元素，禁用点击事件）
  if (modifiers.disabled) {
    // 禁用处理
    disabledHandle(el, flag, arg);
  } else if (modifiers.hidden) {
    // 隐藏处理
    hiddenHandle(el, flag, arg);
  } else {
    // 默认处理（可根据项目需求自行调整）
    hiddenHandle(el, flag, arg);
  }
}

/**
 * 禁用处理
 * @param el
 * @param flag
 * @param arg 参数
 */ // @ts-ignore
function disabledHandle(el, flag, arg = 'permit') {
  el.title = '无操作权限';
  if (flag) {
    el.classList.remove('lg-has-disabled', `lg-has-${arg}`);
    el.removeAttribute('disabled');
  } else {
    el.classList.add('lg-has-disabled', `lg-has-${arg}`);
    el.setAttribute('disabled', 'disabled');
  }
}

/**
 * 隐藏处理
 * @param el
 * @param flag
 * @param arg
 */ // @ts-ignore
function hiddenHandle(el, flag, arg = 'permit') {
  // 使用空节点替换（相当于无权限直接删除元素）
  const cfg = el['$soar.has'];
  if (flag) {
    el.classList.remove('lg-has-hidden', `lg-has-${arg}`);
    el.removeAttribute('hidden');
  } else {
    el.classList.add('lg-has-hidden', `lg-has-${arg}`);
    el.setAttribute('hidden', 'hidden');
  }
}

export default {
  has: {
    mounted(el: any, config: any) {
      // 构造空节点
      const emptyNode = document.createElement('lg-has-not');
      el['$soar.has'] = { parentNode: el.parentNode, emptyNode, hidden: false };
      handle(el, config);
    },
    updated: handle,
  },
};
